#include "Poligon3DSceneNode.h"
#include "../include/CTypes.h"
#include "../include/ISceneNode.h"
#include "../include/PowerLibraryEngine.h"

CPoligon3DSceneNode::CPoligon3DSceneNode(CSceneGenerator *sgen,vector3dvpos Len,IPoligon3D *PolBase,
										 std::vector<bool> *HideFace,ISceneNodeReceiveParams):
IDrawableSceneNode(ISceneNodeBasicParams)
{
	// Create a vector with data about if we have to draw the n-face.
	// There are two options HideFace is NULL and we draw all the faces, or HideFace is not NULL and we select wich faces we have to draw.
	std::vector<bool> DrawFace;
	u32 i;
	if (HideFace)
	{
		for (i=0;i<HideFace->size();i++)
		{
			DrawFace.push_back(!(*HideFace)[i]);
		}
	}
	else
	{
		for (i=0;i<PolBase->GetNumVectors()+2;i++)
		{
			DrawFace.push_back(true);
		}
	}

	// Someone missed values.
	if (i<PolBase->GetNumVectors()+2)
	{
		pLogDebug << "We need more " << PolBase->GetNumVectors() + 2 << " vectors to create the object, you provided only " << i << endl;
		pLogDebug << "Now creating the rest of the faces." << endl;
		for (;i<PolBase->GetNumVectors()+2;i++)
			DrawFace.push_back(false);
	}

	std::vector<vector3dvpos> VecCopy;

	// First, we have to "copy" the polygon source as the first face of the destination.
	IDrawableFace *detemp;
	if (DrawFace[0])
	{
		detemp = new IDrawableFace(PolBase->GetNumVectors());
		detemp->BeginVectors();
	}

	for (u32 i=0;i<PolBase->GetNumVectors();i++)
	{
		vector3dvpos Temp(*(PolBase->GetVector(i)),*(PolBase->GetVector(i)+1),*(PolBase->GetVector(i)+2));
		VecCopy.push_back(Temp);
		if (DrawFace[0])
			detemp->AddVector(&(VecCopy[i]));
	}
	if (DrawFace[0])
	{
		detemp->EndVectors();
		de.push_back(detemp);
	}

	// Now, we have to "translate" the vector.
	if (DrawFace[1])
	{
		detemp = new IDrawableFace(PolBase->GetNumVectors());
		detemp->BeginVectors();
	}

	for (u32 i=0;i<PolBase->GetNumVectors();i++)
	{
		vector3dvpos Temp(*(PolBase->GetVector(i)),*(PolBase->GetVector(i)+1),*(PolBase->GetVector(i)+2));
		VecCopy.push_back(Temp);
		VecCopy[i+PolBase->GetNumVectors()] += Len;
		if (DrawFace[1])
			detemp->AddVector(&(VecCopy[i+PolBase->GetNumVectors()]));
	}
	if (DrawFace[1])
	{
		detemp->EndVectors();
		de.push_back(detemp);
	}

	for (u32 j=0;j<PolBase->GetNumVectors();j++)
	{
		if (DrawFace[2+j])
		{
			detemp = new IDrawableFace(PolBase->GetNumVectors());
			u32 i1 = j+1;
			u32 i2 = j;
			u32 i3 = j + PolBase->GetNumVectors();
			u32 i4 = i3+1;

			if (i1 >= PolBase->GetNumVectors())
				i1 = 0;

			if (i4 >= 2*PolBase->GetNumVectors())
				i4 = PolBase->GetNumVectors();

			detemp->BeginVectors();
			detemp->AddVector(&(VecCopy[i1]));
			detemp->AddVector(&(VecCopy[i2]));
			detemp->AddVector(&(VecCopy[i3]));
			detemp->AddVector(&(VecCopy[i4]));
			detemp->EndVectors();
			de.push_back(detemp);
		}
	}

	VecCopy.clear();
	BBox.SetBoundingBox(de);
}

CPoligon3DSceneNode::~CPoligon3DSceneNode()
{

}

void CPoligon3DSceneNode::Render(IDrawableFaceManager *dfm)
{
	for (u32 i=0;i<de.size();i++)
	{
//		de[i]->UpdateMaterial(&Material);
		dfm->AddToRenderList3D(de[i]);
	}
}
